/*
 * Project: yesoft-core
 * File: FileUtils.java
 * Package: com.yesoft.modules.core.utils
 * Date: 2014年3月26日下午3:28:53
 * Version: V1.0
 * Copyright (c) 2014 YESOFT CHINA, Inc. All Rights Reserved.
 */
package com.ruoyi.ichen.base.utils;

import com.google.common.collect.Lists;
import com.ruoyi.ichen.base.exception.WeCoreException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.activation.FileTypeMap;
import java.io.*;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.DecimalFormat;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName: FileUtils
 * @Description: 文件工具类
 * @author Venlentine
 * @date: 2014年3月26日 下午3:28:53
 */
public class MyFileUtils {
	private static Logger logger = LoggerFactory.getLogger(MyFileUtils.class);

	/**
	 * 链接多节转为路径
	 * @param args
	 * @return
	 */
	public static String join(String... args) {
		String filePath = "";
		for (int i = 0; i < args.length; i++) {
			if (StringUtils.isEmpty(args[i])) {
				continue;
			}
			String arg = args[i];
			arg = StringUtils.stripEnd(arg, "/");//去掉末尾分隔符
			arg = StringUtils.stripEnd(arg, "\\");
			filePath += arg;
			if (i < args.length - 1) {
				filePath += File.separatorChar;
			}
		}
		return filePath;
	}

	/**
	 * 创建文件夹
	 * @param path
	 * @return
	 */
	public static File mkdir(String path) {
		File filePath = new File(path);
		// 当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
		if (!filePath.exists() && !filePath.isDirectory()) {
			filePath.mkdirs();//创建文件夹要用 file.mkdirs();不能用 file.mkdir();否则在linux下运行失败
		}
		return filePath;
	}

	/**
	 * 写入文件内容
	 * @param path
	 * @param content
	 */
	public static void write(String path, String content) {
		try {
			File f = new File(path);
			if (f.exists()) {
				logger.debug("文件存在");
			} else {
				logger.debug("文件不存在，正在创建...");
				if (f.createNewFile()) {
					logger.debug("文件创建成功！");
				} else {
					logger.error("文件创建失败！");
				}
			}
			Files.write(Paths.get(path), (content + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
		} catch (Exception e) {
			logger.error("{}{}", path, e);
		}
	}

	/**
	 * 读取文件内容
	 * @param file
	 */
	public static String read(String file) {
		File f = new File(file);
		if (f.exists()) {
			try {
				byte[] data = Files.readAllBytes(Paths.get(file));
				String content = new String(data, StandardCharsets.UTF_8);
				return content;
			} catch (Exception e) {
				logger.error("{}{}", file, e);
			}
		} else {
			logger.error("文件不存在!");
		}
		return null;
	}

	/**
	 * 获取文件类型
	 * @param pathName
	 * @return
	 */
	public static String getContentType(String pathName) {
		String g = URLConnection.guessContentTypeFromName(pathName);
		if (g == null) {
			g = FileTypeMap.getDefaultFileTypeMap().getContentType(pathName);
		}
		return g;
	}

	/**
	 * 获取文件类型 Spring
	 * @param file
	 * @return
	 */
	/*public static String getContentType(MultipartFile file) {
		String mimeType = file.getContentType();
		if (StringUtils.isBlank(mimeType) && StringUtils.isNotBlank(file.getOriginalFilename())) {
			mimeType = MyFileUtils.getContentType(file.getOriginalFilename());
		}
		return mimeType;
	}*/

	/**
	 * 获取文件扩展名 <br />
	 * 不包含小数点
	 * @param fileName
	 * @return
	 */
	public static String getFileExtension(String fileName) {
		String fileExt = FilenameUtils.getExtension(fileName);
		if (StringUtils.isBlank(fileExt)) {
			throw new WeCoreException(fileName + ":文件没有扩展名");
		}
		return fileExt.toLowerCase();
	}

	/**
	 * byte 转 InputStream
	 * @param buf
	 * @return
	 */
	public static final InputStream byte2Input(byte[] buf) {
		return new ByteArrayInputStream(buf);
	}

	/**
	 * InputStream 转 byte
	 * @param inStream
	 * @return
	 * @throws IOException
	 */
	public static final byte[] input2byte(InputStream inStream) throws IOException {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[1024];
		int rc = 0;
		while ((rc = inStream.read(buff, 0, 1024)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		byte[] in2b = swapStream.toByteArray();
		return in2b;
	}

	/**
	 * InputStream 转 byte
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	@Deprecated
	public static final byte[] readStream(InputStream inStream) throws IOException {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		outStream.close();
		inStream.close();
		return outStream.toByteArray();
	}

	/** 
	 * 返回byte的数据大小对应的文本 
	 * @param size 
	 * @return 
	 */
	public static String formatFileSize(long size) {
		DecimalFormat formater = new DecimalFormat("####.00");
		if (size < 1024) {
			return size + "bytes";
		} else if (size < 1024 * 1024) {
			float kbsize = size / 1024f;
			return formater.format(kbsize) + "KB";
		} else if (size < 1024 * 1024 * 1024) {
			float mbsize = size / 1024f / 1024f;
			return formater.format(mbsize) + "MB";
		} else if (size < 1024 * 1024 * 1024 * 1024) {
			float gbsize = size / 1024f / 1024f / 1024f;
			return formater.format(gbsize) + "GB";
		} else {
			return "size: error";
		}
	}

	/**
	 * 多文件压缩成zip流
	 * @param fileList
	 * @param zipName
	 * @param tempFilePath
	 * @return
	 */
	public static ByteArrayOutputStream fileToZip(List<String> fileList, String zipName, String tempFilePath) {
		byte[] buffer = new byte[1024];
		ZipOutputStream out = null;
		try {
			out = new ZipOutputStream(new FileOutputStream(tempFilePath + zipName));
			for (String file : fileList) {
				File logFile = new File(file);
				FileInputStream fis = new FileInputStream(logFile);
				out.putNextEntry(new ZipEntry(logFile.getName()));
				int dataLen;
				//读入需要下载的文件的内容，打包到zip文件
				while ((dataLen = fis.read(buffer)) > 0) {
					out.write(buffer, 0, dataLen);
				}
				out.closeEntry();
				fis.close();
			}
			out.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		//读取压缩包
		File filezip = new File(tempFilePath + zipName);
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			FileInputStream inStream = new FileInputStream(filezip);
			BufferedInputStream bis = new BufferedInputStream(inStream);
			int c = bis.read();
			while (c != -1) {
				baos.write(c);
				c = bis.read();
			}
			bis.close();
			inStream.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return baos;
	}

	/**
	 * 获取文件列表
	 * @param folderPath
	 * @return
	 */
	public static List<File> findFileList(String folderPath) {
		/*
		 * File file = new File(path); IOFileFilter fileFilter =
		 * DirectoryFileFilter.DIRECTORY; IOFileFilter dirFilter =
		 * TrueFileFilter.TRUE;//子目录处理 List<File> fileList =
		 * Lists.newArrayList(FileUtils.listFilesAndDirs(file, fileFilter,
		 * null)); return fileList;
		 */
		File file = new File(folderPath);
		File[] tempList = file.listFiles();
		return Lists.newArrayList(tempList);
	}

	/**
	 * 文件内容分页读取
	 * @param filePath
	 * @param encode
	 * @param page
	 * @param pageLine
	 * @return
	 */
	public static List<String> findFileContent(String filePath, String encode, int page, int pageLine) {
		List<String> list = Lists.newArrayList();
		try {
			File file = new File(filePath);
			list = FileUtils.readLines(file, encode);
			int total = list.size();
			int pageNum = total / pageLine;
			if (pageNum < 1) {
				pageNum = 1;
			}
			int pageIndex = page > pageNum ? pageNum : page;

			int start = (pageIndex - 1) * pageLine;
			int end = pageIndex * pageLine;

			int fromIdx = total - end;
			int toIdx = total - start;

			fromIdx = fromIdx < 0 ? 0 : fromIdx;
			toIdx = toIdx > total ? total : toIdx;

			// Collections.reverse(list);
			list = list.subList(fromIdx, toIdx);
			list.add(file.getPath());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
		return list;
	}

	public static void main(String[] args) {
		System.out.println(MyFileUtils.read("G:\\Share\\text.txt"));
		//System.out.println(getFileExtension("abcd.jpg"));
	}
}
